#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "hcsr04.h"
#include "led.h"
#include "modbus_rtu.h"
#include "iwdg.h"
#include <string.h>

#if DEBUG
#define DEBUG_OUT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_OUT(fmt, ...)
#endif

// 用于获取返回的距离(mm)
uint16_t gDistance = 0;
// 存放数据
uint8_t data_buf[64] = "";

int main(void)
{
	// 设置中断优先组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	// 延时初始化
	delay_init();
	// 超声波模块初始化
	hsr04_init();
	// led初始化
	led_init();
	// 串口初始化
	uart_init(9600);
	// 独立看门狗初始化
	// iwdg_init();
	// 开机闪烁两下
	led_trigger(2);

	while (1)
	{
#if DEBUG
		// 获取返回液面深度
		// gDistance = Med_Hcsr04_GetLength();
		// printf("gDistance:%d\n",gDistance);
#endif
		// 当串口接收所有数据时触发
		if (USART_RX_STA & 0x8000)
		{
			DEBUG_OUT("--------------------------\n");
			uint8_t ret = modbus_recv(USART_RX_BUF);
			switch (ret)
			{
			case CHECK_SUCC:

				DEBUG_OUT("slave_addr:%02d\n", slave_addr);
				DEBUG_OUT("funcation_code:%02d\n", funcation_code);
				DEBUG_OUT("start_address:%04d\n", start_address);
				DEBUG_OUT("count:%04d\n", count);
				DEBUG_OUT("check_code:%04x\n", check_code);
				DEBUG_OUT("CHECK_SUCC\n");

				// 获取返回液面深度
				gDistance = Med_Hcsr04_GetLength();
				uint16_t ret = htons(gDistance);
				uint8_t data_buf[4] = "";
				memcpy(data_buf, &ret, sizeof(ret));
				// 向寄存器写数据
				modbus_write_reg(start_address, sizeof(ret), data_buf);

				DEBUG_OUT("gDistance:%d\n", gDistance);

				// 数据的长度
				uint8_t data_len = count * 2;

				// 数据类型转换
				// union short_byte data;
				// data.s = (uint16_t)gDistance;
				/*
					uint8_t i = 0;
					// 将2字节按照大端存储的方式存入缓存中
					DATA_BUF[0] = data.b[1];
					DATA_BUF[1] = data.b[0];
					for (i = 0; i < len; i++)
						DATA_BUF[i] = data.b[2 - i];
						*/
				// 组包并发送到Modbus
				modbus_send(slave_addr, funcation_code, start_address, data_len);
				memset(data_buf, 0, 64);
				// LED闪烁提示完成一次输出
				led_trigger(1);
				break;
			case CHECK_ERROR:
				led_trigger(4);

				DEBUG_OUT("slave_addr:%02d\n", slave_addr);
				DEBUG_OUT("funcation_code:%02d\n", funcation_code);
				DEBUG_OUT("start_address:%04d\n", start_address);
				DEBUG_OUT("count:%04d\n", count);
				DEBUG_OUT("check_code:%04x\n", check_code);
				DEBUG_OUT("CHECK_ERROR\n");

				break;
			case SLAVE_ADDR_ERROR:
				led_trigger(3);
				DEBUG_OUT("SLAVE_ADDR_ERROR\n");
				break;
			case FUNCATION_CODE_ERROR:
				DEBUG_OUT("FUNCATION_CODE_ERROR\n");
				break;
			case SET_HEIGHT:
				DEBUG_OUT("SET_HEIGHT\n");
				break;
			default:
				DEBUG_OUT("UNKNOWN_ERROR\n");
				break;
			}
			DEBUG_OUT("--------------------------\n");
			// 重置标志位
			USART_RX_STA = 0;
			// 清空串口缓存
			memset(USART_RX_BUF, 0, USART_REC_LEN);
		}
		// 喂狗防止程序跑飞
		iwdg_feed();
	}
}
